using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading.Tasks;
using CPlatePrintSys.Domain.Models;
using CPlatePrintSys.Domain.Services;
using CPlatePrintSys.Infrastructure.Repositories;
using Newtonsoft.Json;

namespace CPlatePrintSys.Application.Services
{
    /// <summary>
    /// 布局服务实现
    /// </summary>
    public class LayoutService : ILayoutService
    {
        private readonly IPlateAnnotationInfoRepository _plateAnnotationInfoRepository;

        public LayoutService(IPlateAnnotationInfoRepository plateAnnotationInfoRepository)
        {
            _plateAnnotationInfoRepository = plateAnnotationInfoRepository;
        }

        /// <summary>
        /// 执行镜像自动布局
        /// </summary>
        public async Task<bool> ExecuteMirrorAutoLayoutAsync(List<PlateAnnotationInfo> plateAnnotationInfos)
        {
            try
            {
                var mirrorPairs = new List<(PlateAnnotationInfo original, PlateAnnotationInfo mirror)>();

                // 分析标注信息，查找镜像对
                foreach (var info in plateAnnotationInfos)
                {
                    if (info.LayoutMean != LayoutMean.Unprocessed) continue;

                    // 从DXF文件中提取镜像信息
                    if (!string.IsNullOrEmpty(info.DesignDrawingPath) && File.Exists(info.DesignDrawingPath))
                    {
                        var mirrorInfo = await ExtractMirrorInfoFromDxfAsync(info.DesignDrawingPath);
                        if (mirrorInfo != null)
                        {
                            // 查找对应的镜像对象
                            var mirrorObj = plateAnnotationInfos.FirstOrDefault(p => 
                                p.SheetConsistentNo == mirrorInfo.MirrorObjNo && 
                                p.LayoutMean == LayoutMean.Unprocessed);

                            if (mirrorObj != null)
                            {
                                mirrorPairs.Add((info, mirrorObj));
                            }
                        }
                    }
                }

                // 更新镜像对的布局信息
                foreach (var pair in mirrorPairs)
                {
                    var layoutInfo = new LayoutInfo
                    {
                        LayoutMean = "1", // 镜像布局
                        Mirrored = new MirroredLayout
                        {
                            OriginalObjNo = pair.original.SheetConsistentNo,
                            MirrorObjNo = pair.mirror.SheetConsistentNo
                        }
                    };

                    // 更新原始对象
                    pair.original.LayoutMean = LayoutMean.MirrorLayout;
                    pair.original.LayoutInfo = JsonConvert.SerializeObject(layoutInfo);
                    pair.original.MergedInfo = $"{pair.original.SheetConsistentNo}/{pair.mirror.SheetConsistentNo}";
                    await _plateAnnotationInfoRepository.UpdateAsync(pair.original);

                    // 更新镜像对象
                    pair.mirror.LayoutMean = LayoutMean.MirrorLayout;
                    pair.mirror.LayoutInfo = JsonConvert.SerializeObject(layoutInfo);
                    pair.mirror.MergedInfo = $"{pair.original.SheetConsistentNo}/{pair.mirror.SheetConsistentNo}";
                    await _plateAnnotationInfoRepository.UpdateAsync(pair.mirror);
                }

                return true;
            }
            catch (Exception ex)
            {
                // 记录日志
                Console.WriteLine($"镜像自动布局失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 执行手动合并布局
        /// </summary>
        public async Task<bool> ExecuteManualMergeLayoutAsync(List<PlateAnnotationInfo> selectedInfos, double sheetLength, double sheetWidth)
        {
            try
            {
                // 验证合并布局是否可行
                var validation = await ValidateMergeLayoutAsync(selectedInfos, sheetLength, sheetWidth);
                if (!validation.IsValid)
                {
                    throw new InvalidOperationException(validation.ErrorMessage);
                }

                // 计算合并布局
                var mergedLayout = await CalculateMergeLayoutAsync(selectedInfos, sheetLength, sheetWidth);

                var layoutInfo = new LayoutInfo
                {
                    LayoutMean = "2", // 合并布局
                    Merged = mergedLayout
                };

                var layoutInfoJson = JsonConvert.SerializeObject(layoutInfo);
                var mergedInfo = string.Join("/", selectedInfos.Select(s => s.SheetConsistentNo));

                // 更新所有选中的标注信息
                foreach (var info in selectedInfos)
                {
                    info.LayoutMean = LayoutMean.MergedLayout;
                    info.LayoutInfo = layoutInfoJson;
                    info.MergedInfo = mergedInfo;
                    await _plateAnnotationInfoRepository.UpdateAsync(info);
                }

                return true;
            }
            catch (Exception ex)
            {
                // 记录日志
                Console.WriteLine($"手动合并布局失败: {ex.Message}");
                return false;
            }
        }

        /// <summary>
        /// 验证合并布局是否可行
        /// </summary>
        public async Task<(bool IsValid, string ErrorMessage)> ValidateMergeLayoutAsync(List<PlateAnnotationInfo> selectedInfos, double sheetLength, double sheetWidth)
        {
            if (selectedInfos == null || selectedInfos.Count == 0)
            {
                return (false, "请选择要合并的图纸");
            }

            if (selectedInfos.Count < 2)
            {
                return (false, "至少需要选择2个图纸进行合并");
            }

            // 检查钢板尺寸是否满足要求
            var maxLength = selectedInfos.Max(s => s.DesignSpecLength);
            var maxWidth = selectedInfos.Max(s => s.DesignSpecWidth);

            if (maxLength > sheetLength)
            {
                return (false, $"钢板长度({sheetLength})小于最大零件长度({maxLength})，无法合并");
            }

            if (maxWidth > sheetWidth)
            {
                return (false, $"钢板宽度({sheetWidth})小于最大零件宽度({maxWidth})，无法合并");
            }

            // 检查是否已经处理过
            var processedInfos = selectedInfos.Where(s => s.LayoutMean != LayoutMean.Unprocessed).ToList();
            if (processedInfos.Any())
            {
                return (false, $"以下图纸已经处理过，无法重复合并: {string.Join(", ", processedInfos.Select(s => s.SheetConsistentNo))}");
            }

            return (true, string.Empty);
        }

        /// <summary>
        /// 从DXF文件中提取镜像信息
        /// </summary>
        public async Task<MirroredLayout> ExtractMirrorInfoFromDxfAsync(string dxfFilePath)
        {
            // TODO: 实现从DXF文件中提取N、M字段信息的逻辑
            // 这里先提供一个占位符实现
            await Task.Delay(100); // 模拟异步操作

            try
            {
                // 从文件路径中提取对象编号
                var fileName = Path.GetFileNameWithoutExtension(dxfFilePath);
                
                // 假设文件名包含镜像信息，例如：B13B8PN103.dxf 和 B13B8PM103.dxf
                if (fileName.EndsWith("N") || fileName.EndsWith("M"))
                {
                    var baseName = fileName.Substring(0, fileName.Length - 1);
                    var suffix = fileName.Substring(fileName.Length - 1);
                    
                    if (suffix == "N")
                    {
                        return new MirroredLayout
                        {
                            OriginalObjNo = fileName,
                            MirrorObjNo = baseName + "M"
                        };
                    }
                    else if (suffix == "M")
                    {
                        return new MirroredLayout
                        {
                            OriginalObjNo = baseName + "N",
                            MirrorObjNo = fileName
                        };
                    }
                }

                return null;
            }
            catch (Exception ex)
            {
                Console.WriteLine($"提取镜像信息失败: {ex.Message}");
                return null;
            }
        }

        /// <summary>
        /// 计算合并布局的零件位置
        /// </summary>
        public async Task<MergedLayout> CalculateMergeLayoutAsync(List<PlateAnnotationInfo> selectedInfos, double sheetLength, double sheetWidth)
        {
            await Task.Delay(100); // 模拟异步操作

            var mergedLayout = new MergedLayout
            {
                SheetLongth = sheetLength,
                SheetWidth = sheetWidth,
                PartLayouts = new List<PartLayout>()
            };

            double currentX = 0;
            double currentY = 0;
            double maxHeightInRow = 0;

            foreach (var info in selectedInfos.OrderByDescending(s => s.DesignSpecLength))
            {
                // 检查是否需要换行
                if (currentX + info.DesignSpecLength > sheetLength)
                {
                    currentX = 0;
                    currentY += maxHeightInRow;
                    maxHeightInRow = 0;
                }

                // 检查是否超出钢板高度
                if (currentY + info.DesignSpecWidth > sheetWidth)
                {
                    throw new InvalidOperationException($"钢板尺寸不足以容纳所有零件");
                }

                mergedLayout.PartLayouts.Add(new PartLayout
                {
                    SheetConsistentNo = info.SheetConsistentNo,
                    Position = new Position
                    {
                        X = currentX,
                        Y = currentY
                    }
                });

                currentX += info.DesignSpecLength;
                maxHeightInRow = Math.Max(maxHeightInRow, info.DesignSpecWidth);
            }

            return mergedLayout;
        }
    }
} 